package com.fat.thegioivere.utility;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.annotation.SuppressLint;
import android.os.Environment;
import android.util.Log;

/**
 * Class này hổ trợ việc ghi log ra tập tin lưu xuống điện thoại, và show ra
 * trên logcat để theo dõi Exception
 * 
 * @author Trinh Minh Soan
 * 
 */
public class MyLogger {

	private static MyLogger instance = null;
	private static final int MAX_LOGS = 5;
	private static final String FILE_NAME = "TGVeRe.txt";
	private static final String LOG_FOLDER = "fat.thegioivere";

	public enum Level {
		DEBUG, INFO, WARN, ERROR
	}

	private Level level = Level.ERROR;
	private String tag = "";
	@SuppressLint("SimpleDateFormat")
	private SimpleDateFormat format = new SimpleDateFormat(
			"MM/dd/yy HH:mm:ss z");
	@SuppressWarnings("unused")
	private File logFileName;
	private PrintWriter writer;

	private void LoggerSetup(String logFilename, Level level) {
		// close previous
		if (writer != null) {
			writer.flush();
			writer.close();
			writer = null;
		}
		// open new
		this.logFileName = createWriter(logFilename);
		this.level = level;
	}

	/**
	 * Constructor
	 */
	private MyLogger() {
		LoggerSetup(FILE_NAME, Level.INFO);
	}

	/**
	 * singleton
	 */
	public static MyLogger getInstance() {
		if (instance == null) {
			instance = new MyLogger();
		}
		return instance;
	}

	/**
	 * create file log
	 */
	private File createWriter(String logFilename) {
		try {
			String state = Environment.getExternalStorageState();
			if (state.equals(Environment.MEDIA_MOUNTED)) {
				File dir = new File(Environment.getExternalStorageDirectory(),
						LOG_FOLDER);
				if (!dir.mkdirs()) {
					Log.w(tag,
							"Could not create log directory: "
									+ dir.getAbsolutePath());
				}
				File log = new File(dir, logFilename);
				if (log.exists()) {
					rotate(log);
				}
				Log.i(tag, "Opening " + log.getAbsolutePath());
				writer = new PrintWriter(new FileWriter(log), true);
				return log;
			} else {
				Log.w(tag,
						"Could not create log file because external storage state was "
								+ state);
			}
		} catch (IOException e) {
			Log.e(tag, "Failed while opening the log file.", e);
		}

		return null;
	}

	/**
	 * create new file if exist
	 */
	private void rotate(File log) {
		int index = log.getName().lastIndexOf('.');
		if (index < 0)
			index = log.getName().length();
		String prefix = log.getName().substring(0, index);
		String extension = log.getName().substring(index);

		int lastLog = MAX_LOGS - 1;
		File lastLogFile = new File(log.getParentFile(), prefix + "-" + lastLog
				+ extension);
		if (lastLogFile.exists())
			lastLogFile.delete();

		for (int i = lastLog; i >= 1; --i) {
			String filename = prefix + "-" + i + extension;
			File l = new File(log.getParentFile(), filename);
			if (l.exists()) {
				File newLog = new File(log.getParentFile(), prefix + "-"
						+ (i + 1) + extension);
				l.renameTo(newLog);
			}
		}

		log.renameTo(new File(log.getParentFile(), prefix + "-1" + extension));
	}

	private boolean isLoggable(Level level) {
		return level.ordinal() >= this.level.ordinal();
	}

	/**
	 * log info message
	 */
	public void info(String tagName, String message) {
		tag = tagName;
		Log.i(tag, message);
		log(Level.INFO, message);
	}

	/**
	 * log warn message
	 */
	public void warn(String tagName, String message) {
		tag = tagName;
		Log.w(tag, message);
		log(Level.WARN, message);
	}

	/**
	 * log error message
	 */
	public void error(String tagName, String message) {
		tag = tagName;
		Log.e(tag, message);
		log(Level.ERROR, message);
	}

	public void close() {
		if (writer != null) {
			writer.flush();
			writer.close();
			writer = null;
		}
	}

	/**
	 * Write message to log file
	 * 
	 */
	private void log(Level level, String message) {
		if (writer != null && isLoggable(level)) {
			Date date = new Date();
			writer.print("______________________\n" + format.format(date));
			writer.print(" ");
			writer.print("<<" + level.toString() + ">>");
			writer.print(" ");
			writer.print("'" + tag + "'");
			writer.print(" ## ");
			writer.println(message);
		}
	}

}
